package com.wfs.myapp.service.impl;

import com.wfs.myapp.common.ApiResult;
import com.wfs.myapp.common.Constant;
import com.wfs.myapp.entity.domain.bk.BkBirthdayRemind;
import com.wfs.myapp.entity.domain.bk.BkFeedback;
import com.wfs.myapp.entity.domain.bk.BkSendMessage;
import com.wfs.myapp.entity.domain.bk.BkTalkRecord;
import com.wfs.myapp.entity.dto.req.bk.BirthdayRemindReqDto;
import com.wfs.myapp.entity.dto.req.bk.FeedbackReqDto;
import com.wfs.myapp.entity.dto.req.bk.GenerateTalkRecordReqDto;
import com.wfs.myapp.entity.vo.*;
import com.wfs.myapp.enums.*;
import com.wfs.myapp.repository.bk.*;
import com.wfs.myapp.service.GlobalService;
import com.wfs.myapp.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

@Service
@Slf4j
public class GlobalServiceImpl implements GlobalService {

    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    private SearchTopRepository searchTopRepository;

    @Autowired
    private FeedBackRepository feedBackRepository;

    @Autowired
    private BookRepository bookRepository;

    @Autowired
    private BirthdayRemindRepository birthdayRemindRepository;

    @Autowired
    private SendMessageRepository sendMessageRepository;

    @Autowired
    private TalkRecordRepository talkRecordRepository;

    @Value("${base.url}")
    private String baseUrl;

    private List<Integer> BORROWING_STATUS_LIST = Arrays.asList(OrderStatusEnum.BORROWING.getCode(), OrderStatusEnum.APPROVE.getCode(), OrderStatusEnum.EXCEEDING.getCode(), OrderStatusEnum.RETURN.getCode());
    private List<Integer> EXCEEDING_STATUS_LIST = Arrays.asList(OrderStatusEnum.EXCEEDING.getCode());
    private List<Integer> ALL_STATUS_LIST = Arrays.asList(OrderStatusEnum.BORROWING.getCode(), OrderStatusEnum.APPROVE.getCode(), OrderStatusEnum.EXCEEDING.getCode(), OrderStatusEnum.RETURN.getCode(), OrderStatusEnum.DONE.getCode());

    @Value("${talk-record.other-content-pre}")
    private String OTHER_CONTENT_PRE_PATH;

    @Value("${talk-record.my-content-pre}")
    private String MY_CONTENT_PRE_PATH;

    @Value("${talk-record.header}")
    private String HEADER_IMAGE_PATH;

    @Value("${talk-record.result}")
    private String RESULT_PATH;



    @Override
    public ApiResult<String> getNoticeContent() {
        StringBuilder sb = new StringBuilder();
        String SPACE = "                         ";
        List<OrderVo> byStatus = orderRepository.findByStatus(OrderStatusEnum.EXCEEDING.getCode(), 5);
        if (CollectionUtils.isEmpty(byStatus)) {
            return ApiResult.success("天下太平    举杯同庆");
        }
        for (OrderVo vo : byStatus) {
            sb.append(vo.getBorrowUserName());
            sb.append("、");
        }
        sb.append("借书逾期不还，特此，通报批评。");
        return ApiResult.success(sb.toString());
    }

    @Override
    public ApiResult<List<List<ReportDataVo>>> getReportDataList(Long userId) {
        List<List<ReportDataVo>> responseList = new ArrayList<>();
        // input
        List<ReportDataVo> inputList = new ArrayList<>();
        long inputBorrowingCount = orderRepository.countByMasterUserIdAndStatus(OrderDirectionEnum.INPUT.getCode(), userId, BORROWING_STATUS_LIST);
        inputList.add(new ReportDataVo("借阅数量", String.valueOf(inputBorrowingCount)));
        long inputExceedingCount = orderRepository.countByMasterUserIdAndStatus(OrderDirectionEnum.INPUT.getCode(), userId, EXCEEDING_STATUS_LIST);
        inputList.add(new ReportDataVo("逾期数量", String.valueOf(inputExceedingCount)));
        long inputAllCount = orderRepository.countByMasterUserIdAndStatus(OrderDirectionEnum.INPUT.getCode(), userId, ALL_STATUS_LIST);
        inputList.add(new ReportDataVo("借入总数", String.valueOf(inputAllCount)));
        responseList.add(inputList);
        // output
        List<ReportDataVo> outputList = new ArrayList<>();
        long outputBorrowingCount = orderRepository.countByMasterUserIdAndStatus(OrderDirectionEnum.OUTPUT.getCode(), userId, BORROWING_STATUS_LIST);
        outputList.add(new ReportDataVo("借阅数量", String.valueOf(outputBorrowingCount)));
        long outputExceedingCount = orderRepository.countByMasterUserIdAndStatus(OrderDirectionEnum.OUTPUT.getCode(), userId, EXCEEDING_STATUS_LIST);
        outputList.add(new ReportDataVo("逾期数量", String.valueOf(outputExceedingCount)));
        long outputAllCount = orderRepository.countByMasterUserIdAndStatus(OrderDirectionEnum.OUTPUT.getCode(), userId, ALL_STATUS_LIST);
        outputList.add(new ReportDataVo("借出总数", String.valueOf(outputAllCount)));
        responseList.add(outputList);
        return ApiResult.success(responseList);
    }

    @Override
    public ApiResult<PageResponse<List<SearchVo.SearchItem>>> getGuessList(Integer page, Integer size) {
        long total = searchTopRepository.countBookTop(SearchTypeEnum.BOOK.getCode());
        List<SearchVo.SearchItem> bookTop = searchTopRepository.findBookTop(SearchTypeEnum.BOOK.getCode(), (page - 1) * size, size);
        bookTop.forEach(item -> item.setStatusStr(BookStatusEnum.getMsg(item.getStatus())));
        if (bookTop.size() < 10) {
            bookTop = bookRepository.findAllByTime((page - 1) * size, size);
        }
        return ApiResult.success(new PageResponse(bookTop, total, page, size));
    }

    @Override
    public ApiResult<BkFeedback> feedback(FeedbackReqDto feedbackReqDto, Long userId) {
        BkFeedback bkFeedback = new BkFeedback();
        BeanUtils.copyProperties(feedbackReqDto, bkFeedback);
        bkFeedback.setUserId(userId);
        bkFeedback.setStatus(0);
        bkFeedback.setCreatedBy(String.valueOf(userId));
        bkFeedback.setUpdatedBy(String.valueOf(userId));
        return ApiResult.success(feedBackRepository.save(bkFeedback));
    }

    @Override
    public ApiResult<AboutVo> about() {
        return ApiResult.success(new AboutVo(
                "https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2FvwKbo0QEtLBFqhaBiZi0VMINFARGWmsGIwhm4%3Dp13aJCn1553611325177.jpg&thumbnail=660x2147483647&quality=80&type=jpg",
                "科技有限公司",
                "致力于创新和技术发展，专注于提供高质量的解决方案。",
                "矢志成为行业的引领者，为国家发展和社会进步贡献力量。",
                "广东省深圳市科技园路100号",
                "010-12345678",
                "wfs588@126.com"));
    }

    @Override
    public ApiResult<Boolean> birthdayRemind(BirthdayRemindReqDto birthdayRemindReqDto, Long userId) {
        BkBirthdayRemind bkBirthdayRemind = new BkBirthdayRemind();
        bkBirthdayRemind.setUserId(userId);
        bkBirthdayRemind.setName(birthdayRemindReqDto.getName());
        bkBirthdayRemind.setBirthday(birthdayRemindReqDto.getBirthday());
        bkBirthdayRemind.setRemindDate(LocalDateTime.of(birthdayRemindReqDto.getRemindDate(), birthdayRemindReqDto.getRemindTime()));
        bkBirthdayRemind.setRemark(birthdayRemindReqDto.getRemark());
        bkBirthdayRemind.setCreatedBy(String.valueOf(userId));
        bkBirthdayRemind.setUpdatedBy(String.valueOf(userId));
        BkBirthdayRemind save = birthdayRemindRepository.save(bkBirthdayRemind);
        // send message
        BkSendMessage bkSendMessage = new BkSendMessage();
        bkSendMessage.setType(SearchTypeEnum.BIRTHDAY_REMIND.getCode());
        bkSendMessage.setTargetId(save.getId());
        bkSendMessage.setStatus(MessageStatusEnum.UN_SEND.getCode());
        bkSendMessage.setCreatedBy(String.valueOf(userId));
        bkSendMessage.setUpdatedBy(String.valueOf(userId));
        sendMessageRepository.save(bkSendMessage);
        return ApiResult.success(true);
    }


    @Override
    public ApiResult<BkTalkRecord> generateTalkRecord(GenerateTalkRecordReqDto generateTalkRecordReqDto, Long myUserId) {
        try {
            /** 画布设置 */
            // 创建BufferedImage对象
            BufferedImage image = new BufferedImage(Constant.WIDTH, Constant.HEIGHT, BufferedImage.TYPE_INT_RGB);
            // 获取Graphics2D对象
            Graphics2D g2d = image.createGraphics();
            // 设置背景色为RGB(245,245,245),
            g2d.setColor(Constant.BACKGROUND);
            g2d.fillRect(0, 0, Constant.WIDTH, Constant.HEIGHT);
            // 启用抗锯齿
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            /** 添加聊天头 */
            BufferedImage header = ImageIO.read(new File(HEADER_IMAGE_PATH));
            // 在(50,50)位置绘制图片，缩放为200x200
            g2d.drawImage(header, 0, 0, Constant.WIDTH, Constant.HEADER_HEIGHT, null);
            // 设置文字颜色和字体
            g2d.setColor(Color.BLACK);
            Font font = new Font("微软雅黑", Font.PLAIN, 18);
            g2d.setFont(font);
            // 在(300, 200)位置绘制文字
            String otherName = generateTalkRecordReqDto.getOtherName();
            g2d.drawString(otherName, Constant.OTHER_NAME_X, Constant.OTHER_NAME_Y);
            /** 添加聊天内容 **/
            List<GenerateTalkRecordReqDto.Content> contentList = generateTalkRecordReqDto.getContentList();
            Font contentFont = new Font("微软雅黑", Font.PLAIN, 12);    // 聊天内容字体
            g2d.setFont(contentFont);
            for (int i = 0; i < contentList.size(); i++) {
                if (i > 10) break;
                if (contentList.get(i).getIsMy()) {
                    // 右侧
                    BufferedImage myAvatar = ImageIO.read(new File(generateTalkRecordReqDto.getMyAvatar()));
                    this.drawMyInfo(g2d, myAvatar, contentList.get(i).getContent(), i);
                } else {
                    // 左侧
                    BufferedImage otherAvatar = ImageIO.read(new File(generateTalkRecordReqDto.getOtherAvatar()));
                    this.drawOtherInfo(g2d, otherAvatar, contentList.get(i).getContent(), i);
                }
            }
            // 释放Graphics2D资源
            g2d.dispose();
            // 保存图像
            String fileName = myUserId + "_" + DateUtils.dateToString(LocalDateTime.now(), DateUtils.YMDHms) +".png";
            File output = new File(RESULT_PATH + fileName);
            ImageIO.write(image, "png", output);
            System.out.println("图像已成功保存到: " + output.getAbsolutePath());
            // 更新mysql结果地址
            Optional<BkTalkRecord> byId = talkRecordRepository.findById(generateTalkRecordReqDto.getId());
            if (!byId.isPresent()) return ApiResult.error(ResponseCodeEnum.TALK_RECORD_NOT_EXIST);
            BkTalkRecord bkTalkRecord = byId.get();
            String resultUrl = baseUrl + "/file/image"+SearchTypeEnum.TALK_RECORD.getPath()+"?imageName=" + fileName;
            bkTalkRecord.setResultUrl(resultUrl);
            talkRecordRepository.save(bkTalkRecord);
            return ApiResult.success(bkTalkRecord);
        } catch (IOException e) {
            System.out.println("保存图像时出错: " + e.getMessage());
        }
        return ApiResult.success();
    }

    private void drawMyInfo(Graphics2D g2d, BufferedImage myAvatar, String myContent, int line) throws IOException {
        log.info("line * i: {}", Constant.LINE_HEIGHT*line);
        // 头像
        g2d.drawImage(myAvatar, Constant.FIRST_MY_AVATAR_X, Constant.FIRST_OTHER_AVATAR_Y + Constant.LINE_HEIGHT*line, Constant.AVATAR_WIDTH, Constant.AVATAR_WIDTH, null);
        // 名称（不显示自己）
        // 聊天内容背景前置（小尖尖）
        g2d.drawImage(ImageIO.read(new File(MY_CONTENT_PRE_PATH)), Constant.WIDTH - 100, Constant.OTHER_CONTENT_PRE_Y + Constant.LINE_HEIGHT*line, Constant.OTHER_MY_PRE_WIDTH - 2, Constant.OTHER_MY_PRE_HEIGHT-1, null);
        FontMetrics fm = g2d.getFontMetrics();
        // 计算文字区域
        int textWidth2 = fm.stringWidth(myContent);
        int textHeight2 = fm.getHeight();
        // 设置背景色和位置
        // 内容  （800 - 右边距到内容的固定长度 -（x要根据文字长度 *16像素））
        int user2_x = Constant.WIDTH - 80 - textWidth2;
        int user2_y = Constant.FIRST_OTHER_CONTENT_Y + 22 + Constant.LINE_HEIGHT*line;
        g2d.setColor(Constant.MY_CONTENT_BACKGROUND);
        // 绘制圆角矩形背景
        g2d.fillRoundRect(
                user2_x - Constant.CONTENT_PADDING,
                user2_y - textHeight2 + fm.getDescent() - Constant.CONTENT_PADDING,
                textWidth2 + 2 * Constant.CONTENT_PADDING,
                textHeight2 + 2 * Constant.CONTENT_PADDING,
                Constant.ARC_WIDTH,
                Constant.ARC_HEIGHT
        );
        // 绘制文字（覆盖在背景上）
        g2d.setColor(Color.BLACK); // 文字颜色
        g2d.drawString(myContent, user2_x, user2_y);
    }

    private void drawOtherInfo(Graphics2D g2d, BufferedImage otherAvatar, String otherContent, int line) throws IOException {
        log.info("line * i: {}", Constant.LINE_HEIGHT*line);
        // 头像
        g2d.drawImage(otherAvatar, Constant.FIRST_OTHER_AVATAR_X, Constant.FIRST_OTHER_AVATAR_Y + Constant.LINE_HEIGHT*line, Constant.AVATAR_WIDTH, Constant.AVATAR_WIDTH, null);
        // 名称
//            Font userNameFont = new Font("微软雅黑", Font.PLAIN, 12);
//            g2d.setFont(userNameFont);
//            g2d.setColor(Constant.OTHER_CONTENT_PRE_BACKGROUND);
//            g2d.drawString(leftUserName, 75, 108);    // 群聊天才会在内容旁显示名称
        // 内容
        Font contentFont = new Font("微软雅黑", Font.PLAIN, 12);    // 聊天内容字体
        g2d.setFont(contentFont);
        g2d.drawImage(ImageIO.read(new File(OTHER_CONTENT_PRE_PATH)), Constant.OTHER_CONTENT_PRE_X, Constant.OTHER_CONTENT_PRE_Y + Constant.LINE_HEIGHT*line, Constant.OTHER_CONTENT_PRE_WIDTH, Constant.OTHER_CONTENT_PRE_HEIGHT, null);    // 聊天内容背景前置（小尖尖）
        FontMetrics fm = g2d.getFontMetrics();
        // 计算文字区域
        int textWidth = fm.stringWidth(otherContent);
        int textHeight = fm.getHeight();
        // 设置背景色和位置
        int x = Constant.FIRST_OTHER_CONTENT_X;
        int y = Constant.FIRST_OTHER_CONTENT_Y + 22 + Constant.LINE_HEIGHT*line;
        Color bgColor = Color.WHITE;
        // 填充背景矩形（可调整边距）
        int padding = Constant.CONTENT_PADDING;
        g2d.setColor(bgColor);
        // 绘制圆角矩形背景
        g2d.fillRoundRect(
                x - padding,
                y - textHeight + fm.getDescent() - padding,
                textWidth + 2 * padding,
                textHeight + 2 * padding,
                Constant.ARC_WIDTH,
                Constant.ARC_HEIGHT
        );
        // 绘制文字（覆盖在背景上）
        g2d.setColor(Color.BLACK); // 文字颜色
        g2d.drawString(otherContent, x, y);
    }

}
